package com.ccb.jyzx.expand.tiantouonline.exception;

import com.ccb.jyzx.expand.tiantouonline.utils.CommonIdUtils;
import com.ccb.jyzx.expand.tiantouonline.view.response.SimpleResponseResult;
import org.springframework.beans.TypeMismatchException;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

/**
 * 异常增强，以JSON的形式返回给客服端
 * 异常增强类型：NullPointerException,RunTimeException,ClassCastException,
 *              NoSuchMethodException,IOException,IndexOutOfBoundsException
 *              以及springmvc自定义异常等，如下：
 * SpringMVC自定义异常对应的status code
 * Exception HTTP Status Code
 * ConversionNotSupportedException         500 (Internal Server Error)
 * HttpMessageNotWritableException         500 (Internal Server Error)
 * HttpMediaTypeNotSupportedException      415 (Unsupported Media Type)
 * HttpMediaTypeNotAcceptableException     406 (Not Acceptable)
 * HttpRequestMethodNotSupportedException  405 (Method Not Allowed)
 * NoSuchRequestHandlingMethodException    404 (Not Found)
 * TypeMismatchException                   400 (Bad Request)
 * HttpMessageNotReadableException         400 (Bad Request)
 * MissingServletRequestParameterException 400 (Bad Request)
 *
 * @ProjectName: extend
 * @Author: jianghaolin
 * @Version: 1.0
 */
@ControllerAdvice
public class JsonExceptionHandler {

    /*----- INTERNAL SERVER ERROR -----*/

    /**
     * 500 运行时异常
     * @param runtimeException
     * @return
     */
    @ExceptionHandler(RuntimeException.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ResponseBody
    public SimpleResponseResult<String> runtimeExceptionHandler(RuntimeException runtimeException) {
        runtimeException.printStackTrace();
        return new SimpleResponseResult<String>(false,500, CommonIdUtils.createFileId(),"服务器出错,请联系后台管理员~");
    }

    /**
     * 500 空指针异常
     * @param ex
     * @return
     */
    @ExceptionHandler(NullPointerException.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ResponseBody
    public SimpleResponseResult<String> nullPointerExceptionHandler(NullPointerException ex) {
        ex.printStackTrace();
        return new SimpleResponseResult<String>(false,500, CommonIdUtils.createFileId(),"出现了空指针问题，请耐心检查~");
    }


    /*----- REQUEST ERROR -----*/

    /**
     * 400错误
     * @param ex
     * @return
     */
    @ExceptionHandler({HttpMessageNotReadableException.class})
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ResponseBody
    public SimpleResponseResult<String> requestNotReadable(HttpMessageNotReadableException ex){
        System.out.println("400..requestNotReadable");
        ex.printStackTrace();
        return new SimpleResponseResult<String>(false,500, CommonIdUtils.createFileId(),"请核对您的传输格式！");
    }

    /**
     * 400错误 参数类型不匹配
     * @param ex
     * @return
     */
    @ExceptionHandler({TypeMismatchException.class})
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ResponseBody
    public SimpleResponseResult<String> requestTypeMismatch(TypeMismatchException ex){
        System.out.println("400..TypeMismatchException");
        ex.printStackTrace();
        return new SimpleResponseResult<String>(false,400, CommonIdUtils.createFileId(),"参数类型不匹配,参数" + ex.getPropertyName() + "类型应该为" + ex.getRequiredType());
    }

    /**
     * 400错误缺少参数异常
     * @param ex
     * @return
     */
    @ExceptionHandler({MissingServletRequestParameterException.class})
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ResponseBody
    public SimpleResponseResult<String> requestMissingServletRequest(MissingServletRequestParameterException ex){
        System.out.println("400..MissingServletRequest");
        ex.printStackTrace();
        return new SimpleResponseResult<String>(false,400, CommonIdUtils.createFileId(),"缺少必要参数,参数名称为" + ex.getParameterName());
    }

    /**
     * 405错误
     * @return
     */
    @ExceptionHandler({HttpRequestMethodNotSupportedException.class})
    @ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)
    @ResponseBody
    public SimpleResponseResult<String> request405(){
        System.out.println("405...");
        return new SimpleResponseResult<String>(false,405, CommonIdUtils.createFileId(),"请核对您的接口文档，确保请求类型GET/POST无误~");
    }
}
